"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
// 属性装饰器
// 1、基本语法
// target：对于静态属性来说值是类，对于实例属性来说值是类的原型对象
// propertyKey：属性名
function demo0518(target, propertyKey) {
    console.log('demo', target, propertyKey);
}
class Test0518 {
    // 对静态属性使用装饰器时，target是该calss类
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
}
__decorate([
    demo0518
], Test0518.prototype, "name", void 0);
__decorate([
    demo0518
], Test0518.prototype, "age", void 0);
__decorate([
    demo0518
], Test0518, "school", void 0);
// 2、关于属性遮蔽(不是属性装饰器的功能，是为什么要有属性装饰器的原因)
// 如下代码中，当构造器中的this.age = age试图在实例上赋值是，实际上是调用了原型上age属性的set方法
class Demo0518 {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
}
// 当new一个Demo0518实例在Object.defineProperty()前执行时，打印的p0518的数据是:"{name:'xxx',age:'xxx'}"
// const p0518 = new Demo0518('张三',18)
// console.log('p1',p0518)
let value = 130;
Object.defineProperty(Demo0518.prototype, 'age', {
    get() {
        return value;
    },
    set(val) {
        value = val;
    },
});
// 当new一个Demo0518实例在Object.defineProperty()前执行时，打印的p0518的数据是:"{name:'xxx'}",age属性没有了
const p0518 = new Demo0518('张三', 18);
console.log('p1', p0518);
// 原理：因为Object.defineProperty方法在原型对象上添加了一个age属性，于是构造器里的this.age = age执行的时候，会在Demo0518身上查询age属性，本着有则改之，无则添加
//于是在Demo0518实例对象上没有找到age属性，但是在原型对象上找了age属性，于是在原型对象上修改了age的值
// 而Object.defineProperty()写在new实例之后不存在属性遮蔽是因为，this.age = age执行的时候是在实例对象上添加了age属性
// 3、应用举例
// 需求：定义一个State属性装饰器，来监视属性的修改
function State(target, propertyKey) {
    let key = `__${propertyKey}`;
    // 利用__xxx，将属性值绑定在每个对应的实例对象上
    Object.defineProperty(target, propertyKey, {
        get() {
            return this[key];
        },
        set(newValue) {
            console.log(`${propertyKey}的最新值为:${newValue}`);
            this[key] = newValue;
        },
        enumerable: true, // 可枚举性：是否参与循环
        configurable: true //可配置性
    });
}
class PersonTest0518 {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
}
__decorate([
    State
], PersonTest0518.prototype, "name", void 0);
__decorate([
    State
], PersonTest0518.prototype, "age", void 0);
const a0518 = new PersonTest0518('夜南', 18);
a0518.age = 20;
